More results...

Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors
post
page
Python IDE Dashboard

Extracurricular Activity Selector

A high school teacher needs your help! They have been asked to organise a full set of registers for students to take part in some extracurricular activities organised by the school.

There are 100 students in the year group, and each student has selected three preferred activities. Your task is to write a Python program that:

  • Allocates each student to an activity
  • Prioritises their 1st choice, then 2nd, then 3rd
  • Ensures no activity exceeds its maximum capacity
  • Identifies any students who could not be allocated

Available Activities

There are 10 activities available:

  • Rounders
  • Football
  • Basketball
  • Dance
  • Athletics
  • Chess Club
  • Coding Club
  • Arts & Crafts
  • Tennis
  • Badminton

Each activity has a maximum capacity of 10 students.

The Data

Student choices are stored in a CSV file called choices.csv like this:

FirstName,LastName,Choice1,Choice2,Choice3,
James,Bond,Basketball,Athletics,Coding Club,
Lara,Croft,Football,Dance,Athletics,
...

The complete file is provided in the Python IDE provided below.

Python Challenge

Your task is to write a Python program that will :

    Reads the CSV file
    Loops through each student
    Allocates them:

      First choice if available
      Otherwise second choice
      Otherwise third choice

    Keeps track of:

      Students assigned to each activity
      Students who could not be assigned

Example Output

This is what the output of your code would look like:

=== Activity Allocations ===

Football (10 students)
- Lara Croft
- John Smith
...

Basketball (10 students)
- James Bond
...

=== Unallocated Students ===
- Alex Turner
- Sarah Connor

Hints

Check the following hints to help you plan your solution!

  • Use a dictionary to store activities and their current student lists
  • Use the csv module to read the file
  • Think carefully about how to check if an activity is full
  • You may want a separate list for unallocated students

Python Code

We have started the code to help you read and extract the data from the CSV file. Your task is now to complete this code to allocate each students to an activity based on their preferences when possible.

unlock-access

Solution...

The solution for this challenge is available to full members!
Find out how to become a member:
➤ Members' Area

The Goldbach Conjecture (Python Challenge)

The Goldbach Conjecture is an unproven mathematical rule, proposed by Christian Goldbach in 1742, stating that every even integer greater than 2 is the sum of two prime numbers. Despite verification by computers up to 4 x 1018, no formal proof exists, making it one of the oldest unsolved problems in number theory!

Every even number greater than 2 can be expressed as the sum of two prime numbers.

Let’s look at some examples:

  • 10 = 3 + 7
  • 28 = 5 + 23
  • 50 = 3 + 47

Our challenge is to write a Python program that tests this conjecture for any even number provided by the end-user of this program. Our program will need to:

    Ask the user to enter an even number greater than 2
    Find two prime numbers that add up to this number
    Display the result

Example Output

Enter an even number: 28
28 = 5 + 23

Prime Numbers?

A prime number is a whole number greater than 1 that cannot be exactly divided by any whole number other than itself and 1.

The first 20 prime numbers are: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, and 71.

To help test the Goldbach Conjecture, we will use a function isPrime() that takes a whole positive number as a parameter and returns whether or not this number is a prime number. Here is the code for this function:

def isPrime(n):
   if n < 2:
      return False
   for i in range(2, int(n**0.5) + 1):
      if n % i == 0:
         return False
   return True

You can test this function using the following code:

number = int(input("Enter a whole number"))
if isPrime(number):
   print("This number is a prime number!")
else:
   print("This number is a not a prime number!")

Testing the Goldbach Conjecture

We are now going to implement an algorithm to test the Goldbach Conjecture for any given number. We will base our Python code on the following flowchart:

Python Code

Use the following IDE to complete the code for testing the Goldbach conjecture based on the above flowchart:

Extension Task

Tweak your code to use an iterative approach to check all even numbers from 4 up to 1000 and display their prime pairs.

unlock-access

Solution...

The solution for this challenge is available to full members!
Find out how to become a member:
➤ Members' Area

Estimating Pi using the Basel Problem

The Basel Problem

In the 17th century, mathematicians became fascinated by an infinite series known as the Basel Problem.
The question was simple to state but extremely difficult to solve:

What is the exact value of the following infinite series?

1/1² + 1/2² + 1/3² + 1/4² + ...

This can also be written using sigma notation:
\sum_{n=1}^{\infty}(1 / n²)

Many famous mathematicians attempted to solve it, including members of the Bernoulli family who lived in the Swiss city of Basel (hence the name of the problem). However, no one could determine its exact value.

That changed in 1734, when the brilliant mathematician Leonhard Euler discovered something remarkable.

Euler’s Remarkable Discovery

Euler proved that the infinite series actually equals:

\sum_{n=1}^{\infty}(1 / n²) = π² / 6

This result surprised mathematicians because it revealed a deep connection between:

  • Number theory (the sum of reciprocals of squares)
  • Geometry through the constant π

Rearranging Euler’s formula allows us to express π in terms of the series:

π = \sqrt{(6 × \sum_{n=1}^{\infty}(1 / n²))}

This means we can estimate π by computing a partial sum of the series.
The more terms we include, the closer we get to the true value of π.

Approximating π Numerically

Since we cannot compute an infinite number of terms, we approximate the series using the first N values:

π ≈ \sqrt{(6 × \sum_{n=1}^{N}(1 / n²))}

As N increases, the approximation becomes more accurate.
This is a perfect opportunity to use Python and an iterative algorithm to calculate an approximate value of Pi using a large number of iterations (N).

Python Challenge

Your challenge is to write a Python program that estimates the value of π using Euler’s solution to the Basel Problem.

Your program should:

    Ask the user how many terms of the series should be calculated.
    Use a loop to calculate the sum of 1 / n².
    Use Euler’s formula to estimate π.
    Display the estimated value of π.
    Display the difference between your estimate and Python’s math.pi.

Example Output:

How many terms should be used? 10000

Estimated value of Pi: 3.14149
Actual value of Pi: 3.141592653589793
Difference: 0.00010

You can now complete the code using the following Python IDE:

Improving the Accuracy

The accuracy depends on the number of terms used.

Terms (N) Approximation of π
10 3.04936
100 3.13208
1,000 3.14064
10,000 3.14149

The true value of π is approximately 3.14159265359, so the estimate improves steadily as N increases.
However, this method converges relatively slowly compared to modern algorithms such as the Gregory-Leibniz series or the Nilakantha series.

Find out more Python challenges based on estimating π using your Python skills:

unlock-access

Solution...

The solution for this challenge is available to full members!
Find out how to become a member:
➤ Members' Area

Python Challenge: How Secure Is My Password?

Passwords are the first line of defence protecting our online accounts. But how secure is your password really?

In this Python challenge we will create a program that estimates how long it would take for a hacker to guess a password using a brute-force attack.

A brute-force attack works by trying every possible password combination until the correct one is found.

Password Estimated Time to Crack
abc A few milliseconds
password Less than a second
werDFG67g$%^K1e Several years

Check our online password checker tool to estimate how secure your password is, and to estimate how long it would take for for a hacker to crack your password using a brute force attack.

Step 1 – Understanding Password Strength

The difficulty of cracking a password depends on two main factors.

1. Password Length

Longer passwords take much longer to guess.

2. Character Variety

Passwords become stronger if they include:

  • Lowercase letters (a–z)
  • Uppercase letters (A–Z)
  • Numbers (0–9)
  • Symbols (!@#$%^&*)

The more character types used, the larger the number of possible combinations.

Character Type Possible Characters
Lowercase letters 26
Uppercase letters 26
Numbers 10
Symbols ~32

Step 2 – Calculating Possible Passwords

If a password uses N possible characters and has a length of L, the total number of combinations is:

Example:

For a password that only contains 3 lowercase letters of the alphabet:

26³ = 17,576 combinations

Step 3 – Estimating Guessing Speed

Modern brute-force tools can test billions of guesses per second.

For this project we will assume:

1,000,000,000 guesses per second

The time to crack the password is therefore:

Step 4 – Python Program

To create our own “password Security Estimator” we will start by asking the user to enter a password.

password = input("Enter a password: ")

We will then work out the number of possible characters used in this password by evaluating if this password contains lowercase characters, uppercase characters, number digits and punctuation signs.

N = 0

#Let's find out if this password contains lowercase characters
for character in password:
   if character in "abcdefghijklmnopqrstuvwxyz":
      N = N + 26
      break

Now we can repeat this approach to see if the password includes uppercase characters, number digits or punctuation signs:

#Let's find out if this password contains uppercase characters
for character in password:
   if character in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
      N = N + 26
      break

#Let's find out if this password contains number digits
for character in password:
   if character in "0123456789":
      N = N + 10
      break

#Let's find out if this password contains punctuation signs
for character in password:
   if character in "!""#$%&'()*+,-./:;<=>?@[\]^_`{|}~":
      N = N + 32
      break

We can now word out the length of the password:

L = len(password)

We can apply the formula to calculate the total number of possible combinations using the ** operator (to the power of).

combinations = N ** L

The next step is to estimate, how long, in seconds, it would take to a brute force through all these combinations based on an estimate of 1 billion guesses per seconds.

guessesPerSecond = 1000000000
seconds = combinations / guessesPerSecond

Finally we will output the results using the most appropriate unit of time (milliseconds, seconds, minutes, hours, days, months or years). To do so we will create a function to format/convert the number of seconds to the most appropriate unit of time.

def formatTime(seconds):

    if seconds < 0.001:
        return "a few milliseconds"

    if seconds < 60:
        return str(int(seconds)) + " seconds"

    minutes = seconds / 60
    if minutes < 60:
        return str(int(minutes)) + " minutes"

    hours = minutes / 60
    if hours < 24:
        return str(int(hours)) + " hours"

    days = hours / 24
    if days < 365:
        return str(int(days)) + " days"

    months = days / 30
    if months<12:
        return str(int(months)) + " months"

    years = days / 365
    return str(int(years)) + " years"

print("Estimated cracking time: " + formatTime(seconds))

Example Output

Example 1

Enter a password: abc
Estimated cracking time: a few milliseconds
Example 2

Enter a password: password
Estimated cracking time: 0.02 seconds
Example 3

Enter a password: pa$$word!
Estimated cracking time: 85 days

Your Turn

Type the code provided below in the following online IDE and estimate the time it would take to crack the following passwords:

Password Estimated Time?
qwertyuiop
P4$$w0rd
weakpassword
123456789
werDFG67g$%^K1e!

unlock-access

Solution...

The solution for this challenge is available to full members!
Find out how to become a member:
➤ Members' Area

Sports Adviser Program (Python Challenge)

Choosing a sport can be tricky! Some people enjoy team sports, others prefer individual sports. Some love being outdoors, while others prefer indoor activities.

In this Python challenge, you will create a simple sports adviser program that asks the user a series of questions and then recommends a sport based on their answers.

This challenge is perfect for practising:

  • input() statements
  • if / elif / else conditions
  • Boolean logic
  • Simple decision trees

Challenge Objective

Write a Python program that asks the user a few questions about their preferences and then suggests a sport they might enjoy.

Your program should ask questions such as:

  • Do you like team sports?
  • Do you prefer indoor or outdoor sports?
  • Do you enjoy water activities?
  • Do you like fast-paced sports?
  • Do you enjoy contact sports?

Based on the answers, your program will recommend either one or a selection of relevant sports.

Here is a selection of indoor and outdoor sports for you to consider:

Sport Team / Individual Indoor / Outdoor Contact / Non-Contact Fast Paced? Water Based?
Football Team Outdoor Contact Yes No
Basketball Team Indoor Contact Yes No
Rugby Team Outdoor Contact Yes No
Cricket Team Outdoor Non-Contact No No
Swimming Individual Indoor / Outdoor Non-Contact Yes Yes
Surfing Individual Outdoor Non-Contact Yes Yes
Running Individual Outdoor Non-Contact Yes No
Tennis Individual Indoor / Outdoor Non-Contact Yes No
Badminton Individual Indoor Non-Contact Yes No
Golf Individual Outdoor Non-Contact No No
Cycling Individual Outdoor Non-Contact Yes No
Kayaking Individual Outdoor Non-Contact Yes Yes
Volleyball Team Indoor / Outdoor Non-Contact Yes No
Squash Individual Indoor Non-Contact Yes No
Gymnastics Individual Indoor Non-Contact No No
Boxing Individual Indoor Contact Yes No
Karate Individual Indoor Contact Yes No
Rowing Team / Individual Outdoor Non-Contact Yes Yes
Table Tennis Individual Indoor Non-Contact Yes No
Field Hockey Team Outdoor Contact Yes No

Python Code

We have started the code for you, though you will need to complete this code to asks more questions about the user preferences and make more suggestions based on their preferences and on the above list of sports.

Duplicate Detection Algorithms & Big O Notation

One of the most powerful ways to understand Big O Notation is to compare two different ways of solving the same problem.

Duplicate Detection Challenge?

The aim of a duplicate detection algorithm is to determine whether a list of values contains any duplicates.
This sounds simple. But the way we solve it makes a huge difference to performance, especially when the given list contains a large number (n) of values.

The Problem

Imagine we have a list of student ID numbers:

list = [1023, 1087, 1045, 1067, 1036, 1099, 1043, 1022, 1063, 1045, 1039]

In this list of IDs we have one duplicate value: 1045 appears twice.

So let’s investigate an algorithm to detect whether a list contains duplicate values. We will compare two approaches:

  1. A solution using nested for loops (Brute force approach)
  2. A more efficient solution using a set (Hash Table)

Method 1: Using Nested Loops (Brute Force)

With this approach we will compare every element of the list with every other elements.
If any two values match (at different positions), we have found a duplicate.

Algorithm (Pseudocode)
FOR i FROM 0 TO length-1
   FOR j FROM i+1 TO length-1
      IF list[i] == list[j]
         RETURN True
RETURN False
Python Implementation
def has_duplicates_bruteforce(data):
   for i in range(len(data)):
      for j in range(i + 1, len(data)):
         if data[i] == data[j]:
            return True
   return False
Big O Notation?

If the list has n items, the outer loop runs n times.
For each of those, the inner loop runs roughly n times.
Total comparisons are approximately:
n × n = n²

  • n = 100 → 10,000 comparisons
  • n = 1,000 → 1,000,000 comparisons
  • n = 10,000 → 100,000,000 comparisons

That growth is quadratic.
We describe this as O(n²) — Polynomial time complexity.

Method 2: Using a Set (Hash Table)

A set in Python:

  • Stores only unique values
  • Allows very fast lookups using a hashing algorithm (average O(1) – Constant Big O Notation to access data)

With this method we access each value of the list one by one and store them in a hash table to we keep track of values we have already seen.
If we ever see a value that is already in the set we have found a duplicate.

Algorithm (Pseudocode)
CREATE empty set called values

FOR each item in list
   IF item is in values
      RETURN True
   ADD item to values

RETURN False

Python Implementation

def has_duplicates_set(data):
   values = set()
   for item in data:
      if item in values:
         return True
      values.add(item)
   return False
Big O Notation?

With this approach, we loop through the list once (n iterations): O(n).
Set lookups and insertions are (on average) constant time: O(1).

  • n = 100 → 100 checks
  • n = 1,000 → 1,000 checks
  • n = 10,000 → 10,000 checks

We describe this as O(n) — linear time complexity.

Comparing Both Methods

n Brute Force (O(n²)) Set Method (O(n))
100 10,000 checks 100 checks
1,000 1,000,000 checks 1,000 checks
10,000 100,000,000 checks 10,000 checks

The difference becomes enormous very quickly.

We can clearly see that as n increases, the second method based on a linear time complexity – O(n), will perform much better than the first approach based on a polynomial time complexity – O(n²)


Python Code

We have implemented both functions in the Python IDE below. Using the time library we are also measuring how long the computer takes to cehck for duplaicates in our randomly generated lists of 5,000 values (n=5,000) using each approach.

Try increasing the size of the list to:

  • 10,000 values
  • 20,000 values
  • 50,000 values

What happens? You should notice the brute-force version slows dramatically.

Key Big O Takeaway

  • Nested loops over the same data usually lead to a O(n²) time complexity
  • Single loop with constant-time operations usually lead to a O(n) time complexity
  • Smarter data structures such as Sets (Hash tables) can dramatically reduce the time complexity of an algorithm
Tagged with:

The Story of Gauss and 1 + 2 + 3 + … + 100

When learning about algorithms, one of the most important ideas in computer science is the Big O Notation. It helps us measure how efficient an algorithm is — especially as the size of the problem gets bigger.

To introduce this concept, let’s travel back to the classroom of a young mathematical genius: Carl Friedrich Gauss (1777 – 1855).
Legend has it that when Gauss was a child, his teacher asked the class to add all the integers from 1 to 100:

1 + 2 + 3 + 4 + ⋯ + 100

The teacher likely expected the students to take a long time adding each number one by one.

But Gauss noticed a clever pattern.

Gauss’ Clever Pairing Method

Carl Friedrich Gauss wrote down the sum adding all the numbers from 1 to 100 in ascending order (from 1 to 100):

1 + 2 + 3 + 4 + ... + 97 + 98 + 99 + 100

Underneath he wrote the same sum, using the same 100 numbers but this time, writing them in descending order (from 100 to 1):

100 + 99 + 98 + 97 + ... + 4 + 3 + 2 + 1

He then paired all these numbers up and realised that each pair added up to 101:

So the total is of all these pairs is :

Sum of all pairs =  100 × 101 = 10,100

But we now have twice as many numbers as needed to caluclate the sum of all the numbers from 1 to 100. So we need to divide this result by 2:

Sum of all numbers from 1 to 100 = 10,100 / 2 = 5,050 

And just like that, Gauss found the answer instantly. From Gauss’ reasoning, we can generalise his approach using the following formula:

We can apply this formula with n=100 or any other value (e.g. n=1,000 or n=1,000,000)

Using an Algorithms

Now let’s compare two approaches to calculate our sum:

  1. Iterative addition (adding numbers one by one)
  2. Gauss’ formula method

Method 1: Iterative Approach

Algorithm (Pseudocode)
total = 0
FOR i FROM 1 TO 100
    total = total + i
END FOR
PRINT total
Python Implementation
def iterative_sum(n):
    total = 0
    for i in range(1, n+1):
        total += i
    return total

print(iterative_sum(100))

This method performs 100 additions when n = 100.

Method 2: Gauss’ Formula

Algorithm (Pseudocode)
total = n × (n + 1) / 2
PRINT total
Python Implementation
def gauss_sum(n):
    return n * (n + 1) / 2

print(gauss_sum(100))

No matter how large n is, this algorithm performs:

  • 1 addition
  • 1 multiplication
  • 1 division

Python Code

We have implemented both functions in the Python IDE below. Using the time library we are also measuring how long the computer takes to calculate the sum using each approach.

Based on our analysis, we believe that the Gauss formula should be more efficient than an iterative approach especially with a very large number for n (e.g. n=1,000,000).

Comparing Efficiency Using Big O Notation

The Big O Notation is used to describe how the running time of an algorithm grows as the input size (n) increases.

With an iterative approach, the loop used to calculate our sum runs n times.
If:

  • n = 100 → 100 operations
  • n = 1,000 → 1,000 operations
  • n = 1,000,000 → 1,000,000 operations

The completion time of this algorithm is pro-rata to the value of n. This is called O(n) — linear time complexity.


Using the Gauss formula, the formula only needs to be executed once, regardless of n. The algorithm always performs the same number of operations — regardless of n.

  • n = 100 → same steps (~3 operations)
  • n = 1,000 → same steps (~3 operations)
  • n = 1,000,000 → same steps (~3 operations)

This is called O(1) — constant time complexity.

What Happens as n Gets Bigger?

n Iterative Operations Gauss Operations
100 100 ~3
1,000 1,000 ~3
1,000,000 1,000,000 ~3
1,000,000,000 1,000,000,000 ~3

As n grows, the difference becomes enormous.
This is why algorithm efficiency matters.

When evaluating the efficiency of an algorithm, the Big O notation helps us answer the following questions:

  • Will this program scale?
  • What happens when the dataset gets huge?
  • Is there a smarter way to solve this problem?

Gauss did not just calculate a sum. He found a more efficient algorithm.
And that is exactly what computer scientists do every day: they use algorithmic thinking to try to find efficient way of solving a problem.

Tagged with:

Frame-Based Animation on the BBC Micro

One of the fun things you can do in BBC BASIC is create frame-based animations using custom characters.

In this tutorial, we will explain how the following program makes a stickman walk from left to right across the screen.

Here is the code for our animation:

10 MODE 2
20 VDU 23,226,24,24,16,58,84,16,40,72
30 YELLOW$=CHR$(17)+CHR$(3)
40 VDU 23,227,24,24,80,60,16,16,40,36
50 FOR I%=0 TO 19
60    CLS
70    SPRITE$=CHR$(226)
80    IF I%MOD2=0 THEN SPRITE$=CHR$(227)
90    PRINT TAB(I%,10) YELLOW$ SPRITE$
100    PRINT TAB(0,11) "--------------------"
110   FOR WAIT%=1 TO 1000:NEXT WAIT%
120 NEXT I%
130 END

You can use an online BBC Basic emulator to complete his challenge:

Let’s break down this code step-by-step.

Step 1: Choosing a Screen Mode

10 MODE 2

MODE 2 sets the screen to:

  • 20 columns wide
  • 32 rows high
  • 8 colours available
  • Large blocky pixels (great for custom characters!)

This mode is perfect for simple sprite animation.

Step 2: Creating Custom Characters

Check our blog post on how to create your own ASCII characters to reuse in your animation.

Using this online custom character code generator we will create two stickman characters as follows:

First Stickman Frame
20 VDU 23,226,24,24,16,58,84,16,40,72

This redefines character 226.

The numbers after 226 describe the 8 rows of pixels that make up the character.

Each number represents one row of 8 pixels:

  • Each bit in the number turns a pixel ON (1) or OFF (0).
  • So you are effectively designing an 8×8 sprite.

This first design is one pose of the stickman.

Second Stickman Frame
40 VDU 23,227,24,24,80,60,16,16,40,36

This defines character 227.

This is a slightly different pose — maybe the legs are swapped.

Now we have two frames:

  • Character 226 → Stickman pose A
  • Character 227 → Stickman pose B

Switching between them will create the illusion of walking.

Step 3: Setting the Colour

30 YELLOW$=CHR$(17)+CHR$(3)

CHR$(17) tells the BBC Micro we are changing text colour.
CHR$(3) sets the colour to yellow.

So YELLOW$ stores the control codes needed to print yellow text.

Later, when we print the sprite, we include YELLOW$ so the stickman appears yellow.

Remember, in Mode 2, you can choose amongst these 8 colours:

Step 4: Creating the Animation Loop

50 FOR I%=0 TO 19

This loop runs 20 times.
I% controls:

  • The horizontal position of the stickman
  • Which animation frame to use

Step 5: Clearing the Screen

60 CLS

CLS clears the screen each frame.

This is essential for animation — otherwise, the old stickman positions would remain visible.

Step 6: Choosing the Animation Frame

70 SPRITE$=CHR$(226)
80 IF I%MOD2=0 THEN SPRITE$=CHR$(227)

Here is the clever bit!

By default, we use character 226:

If I% MOD 2 = 0, we switch to character 227.

MOD means remainder after division. So:

  • When I% is even → frame 227
  • When I% is odd → frame 226

This alternates the stickman pose every loop, an essential part of our frame-based animation!

Step 7: Moving Across the Screen

90 PRINT TAB(I%,10) YELLOW$ SPRITE$

TAB(I%,10) moves the cursor to:

  • Column = I%
  • Row = 10

Since I% increases each loop, the stickman moves right.

Then we print the colour code and the custom character sprite, so the stickman appears to walk across the screen.

Step 8: Drawing the Ground

100 PRINT TAB(0,11) "--------------------"

This prints a simple floor under the stickman.
It helps give the illusion that the character is walking.

Step 9: Slowing It Down

110 FOR WAIT%=1 TO 1000:NEXT WAIT%

This is a delay loop. Without it, the animation would move too fast to see. The larger the number, the slower the animation.

Step 10: Repeat

120 NEXT I%
130 END

The loop repeats until the stickman reaches the right side of the screen.
Then the program ends.

🎬 How Frame-Based Animation Works

To sum it up, frame-based animation works by:

  • Creating multiple versions of a character (frames)
  • Rapidly switching between them
  • Moving the position slightly each time
  • Adding a small delay

Your brain fills in the gaps and sees movement! This is exactly how early video games worked.

Tagged with: ,

Drawing Shapes on a BBC Micro

In this tutorial, you will learn how to use the MOVE, DRAW, and PLOT commands in BBC BASIC to create and fill shapes.

By the end you will understand:

  • How screen modes work
  • How coordinates work
  • How to draw triangles, rectangles, circles and ellipses
  • How to change colours
  • How to fill shapes properly

You can use an online BBC Basic emulator to complete his challenge:

️BBC Micro Screen Modes

Before we start drawing on the screen let’s investigate the different screen modes available on a BBC Micro.

Effectively using BBC Basic you can change the screen Mode and resolution using the following instruction:

MODE number

When creating a computer program in BBC Basic, there are 8 modes to choose from as described below:

Mode Type Resolution Colours
MODE 0 Graphics 640 × 256 2
MODE 1 Graphics 320 × 256 4
MODE 2 Graphics 160 × 256 16
MODE 3 Text 80 × 25 text 2
MODE 4 Graphics 320 × 256 2
MODE 5 Graphics 160 × 256 4
MODE 6 Graphics 320 × 256 2
MODE 7 Teletext 40 × 25 text 8 (Teletext)

Tip: MODE 2 is great for colourful drawings.

Understanding Coordinates

  • (0,0) is the bottom-left of the screen
  • X increases to the right, from 0 to 1279.
  • Y increases upwards, from 0 to 1023

Note that the (X,Y) coordinates help you position your “pen” on a 1280 x 1024 canvas/screen whatever mode you are opting for for your programme. The resolution set by selecting a mode only impacts on the size of the pixels displayed on screen. (Hence on the number of pixels you can display on the screen). For instance with mode 2, each pixel will be 8 graphic units wide by 4 graphic units wide. Hence you can only display 160 pixels accross the screen. (X,Y) coordinates used when drawing on the screen use graphic units (X between 0 and 1279 and Y between 0 and 1023) instead of pixels.

MOVE() and DRAW() to Draw Lines ✏️

To draw lines and shapes we will mainly use two commands: MOVE() and DRAW().

MOVE moves without drawing.
DRAW draws a line from the current position.

For instance:

10 MODE 2
20 MOVE 100,100
30 DRAW 200,100

This draws a horizontal line on screen.

Drawing a Shape

To draw a shape, we will need to draw each line one by one, joining the relevant set of (X,Y) coordinates.

For instance to draw a rectangle:

10 MODE 2
20 MOVE 150,100
30 DRAW 350,100
40 DRAW 350,200
50 DRAW 150,200
60 DRAW 150,100

Changing Colours

Use GCOL() instruction to change drawing colour:

GCOL 0,2

The second number selects the colour. You can start using the following colour codes for your drawings:

Understanding the PLOT Command

The PLOT() command can be used as either as an alternative to or alongside the DRAW() and MOVE() commands. It enables to draw more complex shapes including circles and ellipses. It is also used to “close shapes” and fill them in with a colour.

The structure of this command is:

PLOT mode, x, y

The first parameter (mode) tells BBC BASIC what type of graphics action to perform.

Filling a Triangle

To fill a triangle, use:

PLOT 85, x, y

85 fills a triangle using:

  • The last two graphics points visited
  • The new coordinate (x,y)

Example:

10 MODE 2
20 GCOL 0,2

30 MOVE 200,100
40 DRAW 300,200
50 DRAW 100,200
70 PLOT 85,200,100

Using BBC Basic it is possible to condense your code by writting multiple instructions on the same line using a colon (:) between each instruction: e.g.

10 MODE 2
20 GCOL 0,2

30 MOVE 200,100:DRAW 300,200:DRAW 100,200:PLOT 85,200,100

Filling a Rectangle

To fill a rectangles, you will need to know the coordinates of the top left and bottom right corners of your rectangle. The commands are:

MOVE xBottomLeft,yBottomLeft
PLOT 101, xTopRight, yTopRight

101 fills the shape formed by:

  • The last visited point (e.g. Bottom left corner)
  • The new (x,y) coordinates (e.g. Top right corner)
  • These two points are used for the two opposite corners of the rectangle to fill in

Example:

10 MODE 2
20 GCOL 0,3
30 MOVE 150,100
40 PLOT 101,350,200

Drawing Circles

The commands to draw a circle outline is:

PLOT 145, radius, 0

Example:

10 MODE 2
20 GCOL 0,3
30 MOVE 200,200 :REM 200,200 are the coordinates for the center
40 PLOT 145,100,0 :REM 145 means draw an outline, 100 is the radius

145 = circle outline.

Filled Circle

The commands to draw a filled circle is:

PLOT 153, radius, 0

Example:

10 MODE 2
20 GCOL 0,3
30 MOVE 300,300 :REM 200,200 are the coordinates for the center
40 PLOT 153,100,0 :REM 153 means draw filled circle, 100 is the radius

153 = filled circle.

Summary Table

Shape Outline Mode Filled Mode
Triangle Use DRAW 85
Rectangle / Parallelogram Use DRAW 101
Circle 145 153

Challenge #1: Drawing Flags by Combining Shapes

Use all the skills described in this blog post to draw the following flags n the screen:

Challenge #2: Complete the 3D Cube

Here is the code to draw a cube in 3D. However some edges are missing. Add the correct MOVE and DRAW commands to complete this code.

10 MODE 2
20 GCOL 0,7

30 REM Front square
40 MOVE 200,200
50 DRAW 400,200
60 DRAW 400,400
70 DRAW 200,400
80 DRAW 200,200

90 REM Back square
40 MOVE 250,250
50 DRAW 450,250
60 DRAW 450,450
70 DRAW 250,450
80 DRAW 250,250

150 REM Connect corners
160 MOVE 200,200
170 DRAW 250,250

180 MOVE 400,200
190 DRAW 450,250

200 REM Add code for the missing edges of our cube...

Extension Task:

  • Fill one face of the cube.
  • Use different colours for each face.
  • Animate the cube by shifting coordinates in a loop.
Tagged with: ,

Bitmap ASCII Characters for the BBC Micro

One of the features that made the BBC Micro such a powerful machine for games programming was the ability to redefine characters and turn text into graphics. Many classic BBC Micro games use custom characters to create sprites, icons and simple animations — all without a dedicated graphics engine.

In this post, you will learn:

  • What ASCII characters are on the BBC Micro
  • How characters are stored as 8×8 bitmaps
  • How the VDU 23 command works
  • How colour is applied to custom characters
  • How to design your own characters using an online tool
  • How to test them in a BBC BASIC emulator

By the end, you will be creating your own sprites using text characters — just like programmers did in the 1980s.

ASCII Characters on the BBC Micro

On the BBC Micro, each character you can print to the screen (letters, numbers, symbols) is represented internally as an 8×8 grid of pixels. Each pixel is either On or Off.

That means every character can be thought of as a tiny bitmap image.

Normally, these characters are built into the system ROM. However, BBC BASIC lets us redefine characters so they display any shape we want. (We will find out how later on in this post)

This is how many games created the different sprites for their games (player sprites, spaceships, enemies, aliens, etc…), all using text mode.

The 8×8 Bitmap Grid

Each character uses and 8×8 grid (8 rows, 8 columns)
Each row is stored as a single number between 0 and 255.

Why 255?
Because each row is actually an 8-bit binary number which is calculated by adding the value of each pixel on the row e.g.

So each one of the 8 rows can be replaced with an 8-bit number (value between 0 and 255):

Redefining Characters with VDU 23

BBC BASIC provides a special command for redefining characters:

VDU 23, character_number, row1, row2, row3, row4, row5, row6, row7, row8

For example:
VDU 23,226,66,36,126,219,189,189,36,102
This tells the BBC Micro to redefine the ASCII character 226, using the eight numbers to describe its pixel rows.

Once defined, the character can be printed like any other:
PRINT CHR$(226)

Applying Colour to Characters

On the BBC Micro, colour is controlled separately from the character bitmap.

In MODE 2, colours are set using control codes from 0 to 7 to access the following colours:

We can can define colours within our code as follows

RED$ = CHR$(17) + CHR$(1)
YELLOW$ = CHR$(17) + CHR$(3)

We can then apply these font colours when printing text or ASCII characters, including our custom made ASCII characters:
PRINT RED$ CHR$(226)
This makes it easy to reuse the same character in different colours.

Online BBC Basic ASCII Character Generator

You can generate your own ASCII characters using our online BBC Basic ASCII Character Generator:

Positioning Characters on the Screen

When writing games, you rarely want your character to appear at the top-left of the screen every time. BBC BASIC provides simple ways to position text characters anywhere on the screen, which works perfectly with custom characters. To do so we will use the TAB(X,Y) function:

RED$ = CHR$(17) + CHR$(1)
PRINT TAB(10,10) RED$ CHR$(226)

When using the TAB() function, BBC BASIC counts the columns and rows from the top-left corner of the screen:

  • X: Column numbers increase from left to right
  • Y: Row numbers increase from top to bottom

Screen Size:
In Mode 2 on the BBC Micro, the screen is configured for 16 colours (The 8 colours describe above using colour codes 0 to 7, and their flashing counterparts colour codes 8 to 15) and has the following text and graphics dimensions:

  • Text Columns: 20 characters per line
  • Text Rows: 32 rows
  • Graphics Resolution: 160 × 256 pixels

Using these dimnesions, here the code needed to place our ASCII character in each of the 4 corners of the screen:

RED$ = CHR$(17) + CHR$(1)
YELLOW$ = CHR$(17) + CHR$(3)
GREEN$ = CHR$(17) + CHR$(2)
BLUE$ = CHR$(17) + CHR$(4)
PRINT TAB(0,0) RED$ CHR$(226)       : REM Top-left corner
PRINT TAB(19,0) YELLOW$ CHR$(226)   : REM Top-right corner
PRINT TAB(0,31) GREEN$ CHR$(226)    : REM Bottom-left corner
PRINT TAB(19,31) BLUE$ CHR$(226)    : REM Bottom-right corner

If you try to print outside this range, the character may wrap around or disappear off screen.

The TAB(X,Y) approach is very useful in video games to position sprites and text on the screen and to implement movements of the different sprites in a frame based game.

You Task 1: Designing Your Own Characters


Create your own ASCII characters using our online BBC Basic ASCII Character Generator.
Use the auto-generated BBC Basic code and test it using an online BBC Basic Emulator.
Position your characters on the screen using the TAB(X,Y) approach.

You Task 2: Design Your Own Splash Screen

Using the same techniques, create your own splash screen for the game Space Invaders!

unlock-access

Solution...

The solution for this challenge is available to full members!
Find out how to become a member:
➤ Members' Area

Tagged with: ,